package com.course.masterservice.impl;

import cn.hutool.crypto.SecureUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.course.component.exceptions.NotLoginException;
import com.course.component.http.requ.RequestToken;
import com.course.component.util.CopyUtil;
import com.course.component.util.DateUtils;
import com.course.component.util.StringUtils;
import com.course.dto.reqs.RequestRole;
import com.course.dto.resp.ResMenu;
import com.course.entity.Permission;
import com.course.entity.User;
import com.course.dto.resp.ResLoginUser;
import com.course.dto.resp.ReturnLoginUser;
import com.course.masterservice.MasterLoginService;
import com.course.masterservice.LoginTokenService;
import com.course.service.IPermissionService;
import com.course.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.Serializable;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @Copyright: Copyright (c)  林中小鸟  All rights reserved.
 * @author: moon
 * @date: 2022/9/15 16:22
 * @Description: **********************
 */
@Service
public class MasterLoginServiceImpl implements MasterLoginService {
    @Resource
    private UserService userService;
    @Resource
    private LoginTokenService tokenService;
    @Autowired
    private IPermissionService permissionService;

    @Override
    public Map<String, Object> getMenu() {
        Map<String, Object> res = new HashMap<>();
        //获取用户的权限信息
        User loginUser = getLoginUser();
        //用户信息获取菜单
        Set<Permission> menuList = userService.getUserMenuAsSet(loginUser);
        loginUser.setMenu(new HashSet<ResMenu>(getMenuTree(menuList)));
        res.put("menu", loginUser.getMenu());
        res.put("permissions", loginUser.getPermissions());
        return res;
    }

    @Override
    public User getUser() {
        return getLoginUser();
    }

    @Override
    public ReturnLoginUser login(RequestToken token) {
        QueryWrapper<User> wrapper = new QueryWrapper<User>();
        wrapper.eq("account", token.getUsername());
        User LoginUser = userService.getOne(wrapper, false);
        if (StringUtils.isNull(LoginUser)) {
            throw new NotLoginException(500, "账号不存在。");
        }
        if (!LoginUser.getPassword().equals(SecureUtil.md5(token.getPassword()))) {
            throw new NotLoginException(500, "密码错误。");
        }
        ResLoginUser resUser = CopyUtil.copy(LoginUser, ResLoginUser.class);

        //获取用户角色
        Set<String> loginRolSet = userService.getUserRolAsSet(LoginUser);
        LoginUser.setRoles(loginRolSet);
        //获取用户权限
        Set<String> loginPermissions = userService.getUserPermissionAsSet(LoginUser);
        LoginUser.setPermissions(loginPermissions);

        //token
        Map<String, Object> newToken = tokenService.createToken(LoginUser);
        resUser.setCreateTime(DateUtils.getNowDate());
        resUser.setUpdateTime(DateUtils.getNowDate());
        resUser.setTokenInfo(newToken);
        resUser.setRole(loginRolSet);
        return new ReturnLoginUser<>((String) newToken.get("access_token"), resUser);
    }

    @Override
    public String getVersion() {
        return "1.6.6";
    }

    @Override
    public User getLoginUser() {
        return tokenService.getLoginUser();
    }

    @Override
    public Set<ResMenu> getMenuAll() {
        List<Permission> menuList = permissionService.list();
        return getMenuTree(new HashSet<>(menuList));
    }

    @Override
    public List<Permission> getMenuRole(RequestRole requestRole) {
        return getPermissionByRoles(Arrays.asList(requestRole.getId().toString()));
    }

    //获取ID的内容
    private List<Permission> getPermissionByRoles(List<String> ids){
        List<Permission> permissions = permissionService.getPermissionByRoleIds(ids);
        permissions.stream().map(item->{
            item.setMeta(JSON.parseObject(item.getMetaJson()));
            item.setPath(item.getUri());
            return item;
        }).collect(Collectors.toList());
        return permissions;
    }

    //生成树
    private Set<ResMenu> getMenuTree(Set<Permission> menuList){
        Set<ResMenu> result = new HashSet<>();
        //list转map
        Map<Long, ResMenu> nodeMap = new LinkedHashMap<>(menuList.size());
        for (Permission treeNode : menuList) {
            treeNode.setMeta(JSON.parseObject(treeNode.getMetaJson()));
            treeNode.setPath(treeNode.getUri());

            nodeMap.put(treeNode.getId(), CopyUtil.copy(treeNode, ResMenu.class));
        }
        for (ResMenu node : nodeMap.values()) {
            if (node.getPid() > 0) {
                ResMenu parent = nodeMap.get(node.getPid());
                if (parent != null && !node.getId().equals(parent.getId())) {
                    parent.getChildren().add(node);
                    continue;
                }
            }
            result.add(node);
        }
        return result;
    }
}
